﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.Mvc;
using Sendz.WebUI.Authorization;
using Sendz.WebUI.Helpers;
using Sendz.WebUI.Models;
using Sendz.Domain;
using Sendz.Model;
using System.Configuration;

namespace Sendz.WebUI.Controllers
{
    // Ref: http://stackoverflow.com/questions/759519/c-centralizing-repeating-viewdata-in-mvc
    [UserInfo] // Reference UserHelpers.cs for attribute override method; allows global user parameter access
    public class AdminController : AjaxFriendlyController
    {
        #region Repository injection //////////////////////////////////

        // Aggregate repositories, injected by container factory in /Infrastructure
        private readonly IUserRepository dbUser;
        private readonly IIdentityRepository dbIdentity;
        private readonly IFormRepository dbForm;
        private readonly IAutoResponderRepository dbAutoResponder;
        public AdminController(IUserRepository dbUser, IIdentityRepository dbIdentity, IFormRepository dbForm, IAutoResponderRepository dbAutoResponder)
        {
            this.dbUser = dbUser;
            this.dbIdentity = dbIdentity;
            this.dbForm = dbForm;
            this.dbAutoResponder = dbAutoResponder;
        }

        #endregion

        #region Action: ListUsers ////////////////////////////

        [Authorize(Roles = "Admin")]
        [HttpGet]
        public ActionResult ListUsers(string sortBy)
        {
            var user = Membership.GetUser(true) as CustomMembershipUser;
            ViewData["AdminKey"] = user.ProviderUserKey;
            var users = dbUser.GetUsers();
            // Allow alternate sorts by other columns
            if (sortBy == "LastLogin")
                users = users.OrderByDescending(u => u.LastLogin).ToList();
            return View(users);
        }

        #endregion

        #region Action: CreateUser (Uses EditUser) ////////////////////////////

        [Authorize(Roles = "Admin")]
        [HttpGet]
        public ActionResult CreateUser()
        {
            ViewData["NewUser"] = true;
            var newUser = new User();
            // Set defaults, this can change
            newUser.ResponsesRemaining = Convert.ToInt16(ConfigurationManager.AppSettings.Get("DefaultResponses"));
            newUser.InvitesRemaining = Convert.ToInt16(ConfigurationManager.AppSettings.Get("DefaultInvites"));
            return View("EditUser", newUser);
        }

        #endregion

        #region Action: EditUser ////////////////////////////

        [Authorize(Roles = "Admin")]
        [HttpGet]
        public ActionResult EditUser(Guid id)
        {
            ViewData["NewUser"] = false;
            return View(dbUser.GetUserByKey(id));
        }

        [Authorize(Roles = "Admin")]
        [HttpPost]
        public ActionResult EditUser(User user, bool newUser)
        {
            if (newUser && user.Password == null)
                ModelState.AddModelError("Password", "A password is required for new users to login");
            if (ModelState.IsValid)
            {
                if (dbUser.SaveUser(user))
                {
                    // Confirmation message valid for a single redirect
                    TempData["Message"] = "The user was successfully saved";
                    return Redirect("/Admin/ListUsers"); // RedirectToAction doesn't work in Ajax.BeginForm with TempData passing through
                }
            }
            // Otherwise, reload the view (& display errors)
            ViewData["NewUser"] = newUser;
            return View(user);
        }

        #endregion

        #region Action: RemoveUser ////////////////////////////

        [Authorize(Roles = "Admin")]
        [HttpGet]
        public ActionResult RemoveUser(Guid id)
        {
            if (dbUser.RemoveUser(id))
                TempData["Message"] = "The user was successfully removed";
            else
                TempData["Message"] = "The user couldn't be removed";
            return Redirect("/Admin/ListUsers");
        }

        #endregion

        #region Action: ResendInvite ///////////////////////////

        [Authorize(Roles = "Admin")]
        [HttpGet]
        public ActionResult ResendInvite(Guid id)
        {
            var thisInvitee = dbUser.GetUserByKey(id);
            if (thisInvitee.LastModified != null)
            {
                ViewData["IsExistingUser"] = true;
                TempData["Message"] = "This user has already responded to the invitation!";
            }
            return View(thisInvitee);
        }

        [Authorize(Roles = "Admin")]
        [HttpPost]
        public ActionResult ResendInvite(Guid id, string message)
        {
            var thisInvitee = dbUser.GetUserByKey(id);
            if (thisInvitee.LastLogin == null)
            {
                var user = Membership.GetUser(true) as CustomMembershipUser;
                var thisUser = dbUser.GetUserByKey((Guid)user.ProviderUserKey);
                var emailHelper = new EmailHelpers();
                if (emailHelper.SendInvite(thisUser, thisInvitee.UserKey, thisInvitee.Firstname + " " + thisInvitee.Lastname, thisInvitee.Email, message))
                {
                    TempData["Message"] = "An email was re-sent to this user with their invitation and link";
                    return Redirect("/Admin/ResendInviteCompleted");
                }
            }
            return View(thisInvitee);
        }

        [Authorize(Roles = "Admin")]
        [HttpGet]
        public ActionResult ResendInviteCompleted()
        {
            return View();
        }

        #endregion

        #region Action: ResetUserPassword ////////////////////////////

        [Authorize(Roles = "Admin")]
        [HttpGet]
        public ActionResult ResetUserPassword(Guid id)
        {
            var thisUser = dbUser.GetUserByKey(id);
            var viewModel = new ResetPasswordViewModel();
            viewModel.UserKey = thisUser.UserKey;
            return View(viewModel);
        }

        [Authorize(Roles = "Admin")]
        [HttpPost]
        public ActionResult ResetUserPassword(ResetPasswordViewModel viewModel)
        {
            // Todo: the client-side validation for the password & confirmation password fields isn't working, relies on server-side -
            // - See the custom validator .cs for more info on the client-side method 
            if (ModelState.IsValid)
            {
                var userHelper = new UserHelpers();
                TempData["Message"] = userHelper.ResetPassword(dbUser.GetUserByKey(viewModel.UserKey), viewModel.Password);
                return Redirect("/Admin/ListUsers");   
            }
            //TempData["Message"] = "Please ensure your password and its confirmation match";
            return View(viewModel);
        }

        [HttpGet]
        public void ResetAdminPassword()
        {
            var thisUser = dbUser.GetUserByName("jon");
            dbUser.ResetUserPassword(thisUser.UserKey, "jon123");
        }

        #endregion

    }
}
